function [globalBest, globalBestFitness, FitnessHistory] = SaDE(popsize, maxIteration,dim, LB, UB, Fun)
% 种群的初始化和计算适应度值
Sol(popsize, dim) = 0; % Declare memory.
Fitness(popsize) = 0;
for i = 1:popsize
    Sol(i,:) = LB+(UB-LB).* rand(1, dim);
    Fitness(i) = Fun(Sol(i,:));
end

% 获得全局最优值以及对应的种群向量
[fbest, bestIndex] = min(Fitness);
globalBest = Sol(bestIndex,:);
globalBestFitness = fbest;

% 策略学习初始化值的设置
p1 = 0.5;
ns1 = 0;
ns2 = 0;
nf1 = 0;
nf2 = 0;
CRm = 0.5;
CRQ = normrnd(CRm,0.1,[popsize,1]);
CRRecord = [];

% 开始迭代
for time = 1:maxIteration
    for i = 1:popsize
        % 突变
        F = normrnd(0.5,0.3);  %正太分布随机数
        if F < 0
            F = 0.0001;
        elseif F > 2
            F = 2;
        end
        if rand() <= p1
            r = randperm(popsize, 3);   %策略1
            mutantPos = Sol(r(1),:) + F * (Sol(r(2),:) - Sol(r(3),:));%在1~pop中随机选择3个数组成一个数组
            tag = 1;
        else
            r = randperm(popsize, 2);   %策略2
            mutantPos = Sol(i,:) + F * (globalBest - Sol(i,:)) + F * (Sol(r(1),:) - Sol(r(2),:));
            tag = 2;
        end

        % 交叉
        jj = randi(dim);  % 选择至少一维发生交叉
        CR = CRQ(i,1);
        for d = 1:dim
            if rand() < CR || d == jj
                crossoverPos(d) = mutantPos(d);
            else
                crossoverPos(d) = Sol(i,d);
            end
        end

        % 检查是否越界.
        crossoverPos(crossoverPos>UB) = UB(crossoverPos>UB);
        crossoverPos(crossoverPos<LB) = LB(crossoverPos<LB);

        evalNewPos = Fun(crossoverPos);% 将突变和交叉后的变量重新评估
        % 小于原有值就更新,同时更新ns1,ns2,nf1,nf2
        if evalNewPos < Fitness(i)
            Sol(i,:) = crossoverPos;
            Fitness(i) = evalNewPos;
            if tag == 1
                ns1 = ns1 + 1;
            elseif tag == 2
                ns2 = ns2 + 1;
            end
            CRRecord = [CRRecord;CR];   
        else
            if tag == 1
                nf1 = nf1 + 1;
            elseif tag == 2
                nf2 = nf2 + 1;
            end
        end
    end
    [fbest, bestIndex] = min(Fitness);
    globalBest = Sol(bestIndex,:);
    globalBestFitness = fbest;

    % 存储每次迭代的最优值.
    FitnessHistory(time) = fbest;

    % 策略的学习
    if mod(time,50) == 0
        p1 = (ns1 * (ns2 + nf2)) / (ns2 * (ns1 + nf1) + ns1 * (ns2 + nf2));
        ns1 = 0;
        ns2 = 0;
        nf1 = 0;
        nf2 = 0;
    end

    % CR的更新
    if mod(time,25) == 0
        CRm = mean(CRRecord);
        CRRecord = [];
    end
    if mod(time,5) == 0
        CRQ = normrnd(CRm,0.1,[popsize,1]);
    end
end
end